#include "timer.h"
#include "PinNames.h"

void enableTimerClock(timer_index_t idx)
{
#if defined(TIM1_BASE)
    if (idx == TIMER1_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    }
#endif
#if defined(TIM2_BASE)
    if (idx == TIMER2_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    }
#endif
#if defined(TIM3_BASE)
    if (idx == TIMER3_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    }
#endif
#if defined(TIM4_BASE)
    if (idx == TIMER4_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    }
#endif
#if defined(TIM5_BASE)
    if (idx == TIMER5_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
    }
#endif
#if defined(TIM6_BASE)
    if (idx == TIMER6_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
    }
#endif
#if defined(TIM7_BASE)
    if (idx == TIMER7_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
    }
#endif
#if defined(TIM8_BASE)
    if (idx == TIMER8_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
    }
#endif
#if defined(TIM9_BASE)
    if (idx == TIMER9_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
    }
#endif
#if defined(TIM10_BASE)
    if (idx == TIMER10_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
    }
#endif
#if defined(TIM11_BASE) && defined(RCC_APB2Periph_TIM11)
    if (idx == TIMER11_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, ENABLE);
    }
#endif
#if defined(TIM12_BASE)
    if (idx == TIMER12_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12, ENABLE);
    }
#endif
#if defined(TIM13_BASE)
    if (idx == TIMER13_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, ENABLE);
    }
#endif
#if defined(TIM14_BASE)
    if (idx == TIMER14_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);
    }
#endif
#if defined(TIM15_BASE) && defined(RCC_APB2Periph_TIM15)
    if (idx == TIMER15_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
    }
#endif
#if defined(TIM16_BASE) && defined(RCC_APB2Periph_TIM16)
    if (idx == TIMER16_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
    }
#endif
#if defined(TIM17_BASE) && defined(RCC_APB2Periph_TIM17)
    if (idx == TIMER17_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17, ENABLE);
    }
#endif
#if defined(TIM18_BASE)
    if (idx == TIMER18_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM18, ENABLE);
    }
#endif
#if defined(TIM19_BASE)
    if (idx == TIMER19_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM19, ENABLE);
    }
#endif
#if defined(TIM20_BASE)
    if (idx == TIMER20_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM20, ENABLE);
    }
#endif
#if defined(TIM21_BASE)
    if (idx == TIMER21_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM21, ENABLE);
    }
#endif
#if defined(TIM22_BASE)
    if (idx == TIMER22_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM22, ENABLE);
    }
#endif
}

void disableTimerClock(timer_index_t idx)
{
#if defined(TIM1_BASE)
    if (idx == TIMER1_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, DISABLE);
    }
#endif
#if defined(TIM2_BASE)
    if (idx == TIMER2_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
    }
#endif
#if defined(TIM3_BASE)
    if (idx == TIMER3_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, DISABLE);
    }
#endif
#if defined(TIM4_BASE)
    if (idx == TIMER4_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, DISABLE);
    }
#endif
#if defined(TIM5_BASE)
    if (idx == TIMER5_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, DISABLE);
    }
#endif
#if defined(TIM6_BASE)
    if (idx == TIMER6_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, DISABLE);
    }
#endif
#if defined(TIM7_BASE)
    if (idx == TIMER7_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, DISABLE);
    }
#endif
#if defined(TIM8_BASE)
    if (idx == TIMER8_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, DISABLE);
    }
#endif
#if defined(TIM9_BASE)
    if (idx == TIMER9_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, DISABLE);
    }
#endif
#if defined(TIM10_BASE)
    if (idx == TIMER10_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, DISABLE);
    }
#endif
#if defined(TIM11_BASE)  && defined(RCC_APB2Periph_TIM11)
    if (idx == TIMER11_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, DISABLE);
    }
#endif
#if defined(TIM12_BASE)
    if (idx == TIMER12_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12, DISABLE);
    }
#endif
#if defined(TIM13_BASE)
    if (idx == TIMER13_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, DISABLE);
    }
#endif
#if defined(TIM14_BASE)
    if (idx == TIMER14_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, DISABLE);
    }
#endif
#if defined(TIM15_BASE)  && defined(RCC_APB2Periph_TIM15)
    if (idx == TIMER15_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, DISABLE);
    }
#endif
#if defined(TIM16_BASE)  && defined(RCC_APB2Periph_TIM16)
    if (idx == TIMER16_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, DISABLE);
    }
#endif 
#if defined(TIM17_BASE)  && defined(RCC_APB2Periph_TIM17)
    if (idx == TIMER17_INDEX)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17, DISABLE);
    }
#endif
#if defined(TIM18_BASE)
    if (idx == TIMER18_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM18, DISABLE);
    }
#endif
#if defined(TIM19_BASE)
    if (idx == TIMER19_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM19, DISABLE);
    }
#endif
#if defined(TIM20_BASE)
    if (idx == TIMER20_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM20, DISABLE);
    }
#endif
#if defined(TIM21_BASE)
    if (idx == TIMER21_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM21, DISABLE);
    }
#endif
#if defined(TIM22_BASE)
    if (idx == TIMER22_INDEX)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM22, DISABLE);
    }
#endif
}

IRQn_Type getTimerIrq(TIM_TypeDef *tim)
{
    IRQn_Type IRQn = NonMaskableInt_IRQn;

    if (tim != (TIM_TypeDef *)NC)
    {
        switch ((uint32_t)tim)
        {
#if defined(TIM1_BASE)
        case TIM1_BASE:
            IRQn = TIM1_UP_IRQn;
            break;
#endif
#if defined(TIM2_BASE)
        case TIM2_BASE:
            IRQn = TIM2_IRQn;
            break;
#endif
#if defined(TIM3_BASE)
        case TIM3_BASE:
            IRQn = TIM3_IRQn;
            break;
#endif
#if defined(TIM4_BASE)
        case TIM4_BASE:
            IRQn = TIM4_IRQn;
            break;
#endif
        default:
            break;
        }
    }

    return IRQn;
}

IRQn_Type getTimerCCIrq(TIM_TypeDef *tim)
{
    IRQn_Type IRQn = NonMaskableInt_IRQn;
    if (tim != (TIM_TypeDef *)NC)
    {
        switch ((uint32_t)tim)
        {
#if defined(TIM1_BASE)
        case TIM1_BASE:
            IRQn = TIM1_CC_IRQn;
            break;
#endif
#if defined(TIM2_BASE)
        case TIM2_BASE:
            IRQn = TIM2_IRQn;
            break;
#endif
#if defined(TIM3_BASE)
        case TIM3_BASE:
            IRQn = TIM3_IRQn;
            break;
#endif
#if defined(TIM4_BASE)
        case TIM4_BASE:
            IRQn = TIM4_IRQn;
            break;
#endif
        default:
            _Error_Handler("TIM: Unknown timer IRQn", (int)tim);
            break;
        }
    }
    return IRQn;
}

uint8_t getTimerClkSrc(TIM_TypeDef *tim)
{
    uint8_t clkSrc = 0;

    if (tim != (TIM_TypeDef *)NC)
    {
        switch ((uint32_t)tim)
        {
#if defined(TIM2_BASE)
        case (uint32_t)TIM2:
#endif
#if defined(TIM3_BASE)
        case (uint32_t)TIM3:
#endif
#if defined(TIM4_BASE)
        case (uint32_t)TIM4:
#endif
#if defined(TIM5_BASE)
        case (uint32_t)TIM5:
#endif
#if defined(TIM6_BASE)
        case (uint32_t)TIM6:
#endif
#if defined(TIM7_BASE)
        case (uint32_t)TIM7:
#endif
#if defined(TIM12_BASE)
        case (uint32_t)TIM12:
#endif
#if defined(TIM13_BASE)
        case (uint32_t)TIM13:
#endif
#if defined(TIM14_BASE)
        case (uint32_t)TIM14:
#endif
#if defined(TIM18_BASE)
        case (uint32_t)TIM18:
#endif
            clkSrc = 1;
            break;
#if defined(TIM1_BASE)
        case (uint32_t)TIM1:
#endif
#if defined(TIM8_BASE)
        case (uint32_t)TIM8:
#endif
#if defined(TIM9_BASE)
        case (uint32_t)TIM9:
#endif
#if defined(TIM10_BASE)
        case (uint32_t)TIM10:
#endif
#if defined(TIM11_BASE)
        case (uint32_t)TIM11:
#endif
#if defined(TIM15_BASE)
        case (uint32_t)TIM15:
#endif
#if defined(TIM16_BASE)
        case (uint32_t)TIM16:
#endif
#if defined(TIM17_BASE)
        case (uint32_t)TIM17:
#endif
#if defined(TIM19_BASE)
        case (uint32_t)TIM19:
#endif
#if defined(TIM20_BASE)
        case (uint32_t)TIM20:
#endif
#if defined(TIM21_BASE)
        case (uint32_t)TIM21:
#endif
#if defined(TIM22_BASE)
        case (uint32_t)TIM22:
#endif
            clkSrc = 2;
            break;
        default:
            _Error_Handler("TIM: Unknown timer instance", (int)tim);
            break;
        }
    }

    return clkSrc;
}